﻿using System;
using Runtime.Common.Object;
using Runtime.CoreAttribute;
using Runtime.ObjectBehaviour.Interface;
using Runtime.Common.Interface;
using Runtime.Common.Interface.GameWorld.Core.Interface;
using Runtime.Data.Interface;

namespace Runtime.DesignPattern
{
    [IgnoreStaticObjectRestore]
    public abstract class GameSingleton<T> : IGameSingleton, IInit where T : IGameSingleton
    {
        private static readonly object _lock = new object();
        private static volatile bool _isDestroyed;
        private static Lazy<T> _Inst = new Lazy<T>(() => Activator.CreateInstance<T>(), true);

        public static T Inst
        {
            get
            {
                if (_isDestroyed)
                {
                    throw new InvalidOperationException($"Singleton {typeof(T).Name} has been destroyed and cannot be accessed.");
                }
                return _Inst.Value;
            }
        }

        public IGuidObject Id { get; } = new GuidObject();

        public void Destroy()
        {
            if (_isDestroyed) return;

            lock (_lock)
            {
                if (_isDestroyed) return;

                try
                {
                    OnDestroy();
                    SingletonRegister.Unregister(this);
                    _Inst = new Lazy<T>(() => Activator.CreateInstance<T>(), true);
                    _isDestroyed = false;
                }
                catch (Exception ex)
                {
                    UnityEngine.Debug.LogError($"Error destroying singleton {typeof(T).Name}: {ex}");
                    throw;
                }
            }
        }

        public virtual void Init()
        {
            if (_isDestroyed)
            {
                throw new InvalidOperationException($"Cannot initialize destroyed singleton {typeof(T).Name}");
            }

            try
            {
                SingletonRegister.Register(_Inst.Value);
            }
            catch (Exception ex)
            {
                UnityEngine.Debug.LogError($"Error initializing singleton {typeof(T).Name}: {ex}");
                throw;
            }
        }

        protected virtual void OnDestroy()
        {
            // Override this method to perform cleanup in derived classes
        }
    }
}